LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY mem_test_cntrl IS
	PORT (
		--THESE PORTS SHOULD BE PORTMAPPED TO PHYSICAL PINS
		clk_50		: IN STD_LOGIC;
		test_en_n	: IN STD_LOGIC;
		mem_busy	: IN STD_LOGIC;
		
		--
		mem_ptr		: OUT STD_LOGIC_VECTOR(8 DOWNTO 0) := "000000000";
		rom_en		: OUT STD_LOGIC := '1';
		wr_req		: OUT STD_LOGIC := '0'
	);
END mem_test_cntrl;

ARCHITECTURE Behavior OF mem_test_cntrl IS
	TYPE State_type IS (IDLE, PAUSE, READ, WRITE, TEST);
	SIGNAL y : State_type := IDLE;
	SIGNAL rom_addr : STD_LOGIC_VECTOR(8 DOWNTO 0) := (OTHERS => '0');
	SIGNAL test_index : INTEGER RANGE 0 TO 511 := 0;
	SIGNAL test_delay : STD_LOGIC_VECTOR(25 DOWNTO 0) := (OTHERS => '0');
	SIGNAL writing : STD_LOGIC := '0';
BEGIN
	PROCESS (clk_50)
	BEGIN
		IF (clk_50'EVENT AND clk_50='1') THEN
			IF (y = IDLE) THEN
				--IDLE
				rom_en <= '1';
				wr_req <= '0';
				test_delay <= (OTHERS => '0');
				writing <= '0';
				
				IF (test_en_n = '0') THEN
					mem_ptr <= rom_addr;
					--y <= TEST;
					y <= PAUSE;
				END IF;
			ELSIF (y = PAUSE) THEN
				--wait
				IF (test_delay = X"FFFFFF") THEN --X"2FAF080" = 1 sec@50MHz****
					test_delay <= (OTHERS => '0');
					y <= TEST;
				ELSE
					test_delay <= test_delay + 1;
				END IF;
			ELSIF (y = WRITE) THEN
				IF (writing = '1') THEN
					writing <= '0';
					wr_req <= '0';
					rom_addr <= rom_addr + 1;
					mem_ptr <= rom_addr;
				END IF;
				IF (writing = '0' AND mem_busy = '0') THEN
					y <= TEST;--*************************************
				END IF;
			ELSIF (y = TEST) THEN
				IF (test_delay = X"0") THEN--**********************
					test_delay <= (OTHERS => '0');
					IF (test_index < 5) THEN
						test_index <= (test_index + 1);
						wr_req <= '1';
						writing <= '1';
						y <= WRITE;
					ELSE
						test_index <= 0;
						y <= IDLE;
					END IF;
				ELSE
					test_delay <= test_delay + 1;
				END IF;
			END IF;
		END IF;
	END PROCESS;
END Behavior;